#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#include "vm.h"

int main(int argc, char* argv[]){

	FILE* fileStream;

	brain10 vm;
	sprintf(vm.R, "%s", "0000");
	sprintf(vm.SP, "%s", "0000");
	sprintf(vm.IC, "%s", "00");
	vm.C = '-';

	print(&vm, 0);
	
	/*if a file was passed from command line*/
	if(argc == 2){
		fileStream = loadProgram(&vm, argv[1]);	
	}else{
		char file[50];
		printf("Filename of brain program: ");
		scanf("%s", file);
		fileStream = loadProgram(&vm, file);
	}
	


	/* main execution loop */
	int ic = 0; //instruction count
	while(ic < 100){
//		char tmp[222];
//		scanf("%s",tmp);

		ic = atoi(vm.IC);

		/* get the instruction */
		char instruction[3];
		instruction[2] = '\0';
		strncpy(instruction, vm.memory[ic], 2);

		/* get the args */
		char args[3] = { vm.memory[ic][2], vm.memory[ic][3], '\0'};
		int x1x2 = atoi(args);



		/* dump registers */
		printf("Instruction : %s\n", instruction);
		printf("Operands    : %s\n", args);


		if( strncmp(instruction, "LR", 2) == 0 ){
			LR(&vm, x1x2);
		}else if( strncmp(instruction, "LL", 2) == 0 ){
			LL(&vm, x1x2);
		}else if( strncmp(instruction, "LH", 2) == 0 ){
			LH(&vm, x1x2);
		}else if( strncmp(instruction, "SR", 2) == 0 ){
			SR(&vm, x1x2);
		}else if( strncmp(instruction, "SP", 2) == 0 ){
			SP(&vm);
		}else if( strncmp(instruction, "PS", 2) == 0 ){
			PS(&vm);
		}else if( strncmp(instruction, "PH", 2) == 0 ){
			PH(&vm);
		}else if( strncmp(instruction, "PP", 2) == 0 ){
			PP(&vm);
		}else if( strncmp(instruction, "CE", 2) == 0 ){
			CE(&vm, x1x2);
		}else if( strncmp(instruction, "CL", 2) == 0 ){
			CL(&vm, x1x2);
		}else if( strncmp(instruction, "BT", 2) == 0 ){
			if(BT(&vm, args)){
				ic = atoi(vm.IC) -1;
			}
		}else if( strncmp(instruction, "BU", 2) == 0 ){
			BU(&vm, args);
			ic = atoi(vm.IC) -1;
		}else if( strncmp(instruction, "GD", 2) == 0 ){
			GD(&vm, x1x2, fileStream);
		}else if( strncmp(instruction, "PD", 2) == 0 ){
			PD(&vm, x1x2);
		}else if( strncmp(instruction, "AD", 2) == 0 ){
			AD(&vm, x1x2);
		}else if( strncmp(instruction, "SU", 2) == 0 ){
			SU(&vm, x1x2);
		}else if( strncmp(instruction, "MU", 2) == 0 ){
			MU(&vm, x1x2);
		}else if( strncmp(instruction, "DI", 2) == 0 ){
			DI(&vm, x1x2);
		}else if( strncmp(instruction, "AS", 2) == 0 ){
			AS(&vm);
		}else if( strncmp(instruction, "SS", 2) == 0 ){
			SS(&vm);
		}else if( strncmp(instruction, "MS", 2) == 0 ){
			MS(&vm);
		}else if( strncmp(instruction, "DS", 2) == 0 ){
			DS(&vm);
		}else if( strncmp(instruction, "NP", 2) == 0 ){

		}else if( (strncmp(instruction, "HA", 2) == 0) || strncmp(instruction, "H", 1) == 0  ){
			printf("***********************\n");
			printf("*     Final State     *\n");
			printf("***********************\n");
			print(&vm, 22);
			exit(0);
		}else{
			printf("Operation not recognized, exiting");
			exit(1);
		}

		print(&vm, 22);
		ic++;
		snprintf(vm.IC, 3, "%.2i", ic); //update register

	}

	
	return 0;
}

